#define _CRT_SECURE_NO_WARNINGS 1
#include "SingleList.h"

//节点的创建
SLNode* BuyNode(SingleListdatatype x)
{
	SLNode* node = (SLNode*)malloc(sizeof(SLNode));
	if (node == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	node->val = x;
	node->next = NULL;
	return node;
}

//链表的打印
void SLNodePrint(SLNode* plist)
{
	while (plist)//plist != NULL
	{
		printf("%d->", plist->val);
		plist = plist->next;
	}
	printf("NULL\n");
}

//尾插
void SLNodepushback(SLNode** plist, SingleListdatatype x)
{
	assert(plist);

	SLNode* newnode = BuyNode(x);//新节点

	if (*plist == NULL)
	{
		//空链表
		*plist = newnode;
	}
	else
	{
		//非空链表
		//遍历原链表，找到尾节点
		SLNode* pcur = *plist;
		while (pcur->next)//(*plist)->next != NULL
		{
			pcur = pcur->next;
		}
		pcur->next = newnode;
	}
}

//头插
void SLpushfront(SLNode** plist, SingleListdatatype x)
{
	assert(plist);

	SLNode* newnode = BuyNode(x);
	newnode->next = *plist;
	*plist = newnode;
}

//尾删
void SLpopback(SLNode** plist)
{
	assert(plist && *plist);//*plist != NULL防止链表为空

	if (!((*plist)->next))//(*plist)->next == NULL
	{
		//链表只有一个节点
		free(*plist);
		*plist = NULL;
	}
	else
	{
		//链表有多个节点
		SLNode* pcur = *plist;//记录倒数第二个节点
		SLNode* del = *plist;//记录尾节点
		while (del->next)
		{
			pcur = del;
			del = del->next;
		}
		pcur->next = NULL;
		free(del);
		del = NULL;
	}
}

//头删
void SLpopfront(SLNode** plist)
{
	assert(plist && *plist);//链表不能为空

	SLNode* next = (*plist)->next;
	free(*plist);
	*plist = next;
}

//查找
SLNode* SLFind(SLNode* plist, SingleListdatatype x)
{
	assert(plist);

	SLNode* pcur = plist;
	while (pcur)
	{
		if (pcur->val == x)
		{
			return pcur;
		}
		pcur = pcur->next;
	}
	return NULL;
}

//在指定位置之前插入数据
void SLposfront(SLNode** plist, SLNode* pos, SingleListdatatype x)
{
	assert(plist && *plist);//链表不能为空，否则找不到指定位置
	assert(pos);

	if (pos == *plist)
	{
		//pos节点就是第一个节点
		//调用头插方法
		SLpushfront(plist,x);
	}
	else
	{
		//pos节点不是第一个节点
		SLNode* newnode = BuyNode(x);
		SLNode* pcur = *plist;
		SLNode* prev = *plist;
		while (pcur)
		{
			if (pcur->val == pos->val)
			{
				break;
			}
			prev = pcur;
			pcur = pcur->next;
		}
		// prev newnode pcur/pos
		prev->next = newnode;
		newnode->next = pcur;
	}
}

//在指定位置之后插入数据
void SLposback(SLNode* pos, SingleListdatatype x)
{
	assert(pos);
	SLNode* newnode = BuyNode(x);
	//pos newnode pos->next
	newnode->next = pos->next;
	pos->next = newnode;
}

//删除pos节点
void slpoppos(SLNode** plist, SLNode* pos)
{
	assert(plist && *plist);
	assert(pos);

	if (*plist == pos)
	{
		//pos是头节点，调用头删方法
		SLpopfront(plist);
	}
	else
	{
		SLNode* prev = *plist;
		while (prev->next != pos)
		{
			//找到pos的前一个节点
			prev = prev->next;
		}
		//prev pos pos->next
		prev->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

//删除pos节点后一个节点
void slpopposback(SLNode* pos)
{
	assert(pos && pos->next);//pos->next != NULL避免pos是尾节点

	SLNode* Next = pos->next;
	pos->next = pos->next->next;
	free(Next);
	Next = NULL;
}

//销毁链表
void DestorySL(SLNode** plist)
{
	assert(plist && *plist);
	SLNode* Next = (*plist)->next;
	while (Next)
	{
		free(*plist);
		*plist = Next;
		Next = Next->next;
	}
	free(*plist);
	*plist = NULL;
}